/*******************************************************************************
 *    系统名称   ：GMAgent服务系统
 *    公司      ： 成都欢娱乐互动
 *    文件名    ： ByteBuffer.java
 *              (C) Copyright joyct Corporation 2011
 *               All Rights Reserved.
 * *****************************************************************************
 *    注意： 本内容仅限于 成都欢娱乐互动公司内部使用，禁止转发
 ******************************************************************************/
package com.ricky.core.net;

import java.io.*;

/***
 * ByteBuffer.java</br>
 * 
 * @author pu
 * @Data 2011-11-1</br>
 * @version v0.1</br>
 * @Discription
 ***/
public final class ByteBuffer implements Cloneable {
	public void position(int i) {
		readPos = writePos = i;
	}

	public void readFrom(InputStream inputstream) throws IOException {
		readFrom(inputstream, capacity() - length());
	}

	public void skipBytes(int i) {
		readPos += i;
	}

	public void readFrom(InputStream inputstream, int i) throws IOException {
		ensureCapacity(writePos + i);
		for (int j = 0; j < i; j += inputstream.read(data, writePos + j, i - j))
			;
		writePos += i;
	}

	public int capacity() {
		return data.length;
	}

	private void ensureCapacity(int i) {
		if (i > data.length) {
			byte abyte0[] = new byte[(i * 3) / 2];
			System.arraycopy(data, 0, abyte0, 0, writePos);
			data = abyte0;
		}
	}

	public void writeTo(OutputStream outputstream) throws IOException {
		int i = available();
		for (int j = 0; j < i; j++)
			outputstream.write(data[readPos++]);
	}

	public void pack() {
		if (readPos == 0)
			return;
		int i = available();
		for (int j = 0; j < i; j++)
			data[j] = data[readPos++];
		readPos = 0;
		writePos = i;
	}

	public void writeByte(int i) {
		writeNumber(i, 1);
	}

	public int readByte() {
		return data[readPos++];
	}

	public int readUnsignedByte() {
		return data[readPos++] & 0xff;
	}

	@SuppressWarnings("unused")
	private void read(byte abyte0[], int i, int j, int k) {
		System.arraycopy(data, k, abyte0, i, j);
	}

	public int getReadPos() {
		return readPos;
	}

	public void setReadPos(int i) {
		readPos = i;
	}

	@SuppressWarnings("unused")
	private void write(byte abyte0[], int i, int j, int k) {
		ensureCapacity(k + j);
		System.arraycopy(abyte0, i, data, k, j);
	}

	public void writeChar(char c) {
		writeNumber(c, 2);
	}

	public char readChar() {
		return (char) (int) (readNumber(2) & 65535L);
	}

	private void writeNumber(long l, int i) {
		ensureCapacity(writePos + i);
		for (int j = 0; j < i; j++) {
			data[writePos++] = (byte) (int) l;
			l >>= 8;
		}
	}

	private long readNumber(int i) {
		long l = 0L;
		for (int j = 0; j < i; j++)
			l |= (long) (data[readPos++] & 0xff) << (j << 3);
		return l;
	}

	public byte[] getBytes() {
		byte abyte0[] = new byte[length()];
		System.arraycopy(data, 0, abyte0, 0, abyte0.length);
		return abyte0;
	}

	public Object clone() {
		ByteBuffer bytebuffer = new ByteBuffer(writePos);
		System.arraycopy(data, 0, bytebuffer.data, 0, writePos);
		bytebuffer.writePos = writePos;
		bytebuffer.readPos = readPos;
		return bytebuffer;
	}

	public void writeAnsiString(String s) {
		if (s == null || s.length() == 0) {
			writeShort(0);
		} else {
			if (s.length() > 32767)
				throw new IllegalArgumentException("string over flow");
			byte abyte0[] = s.getBytes();
			writeShort(abyte0.length);
			writeBytes(abyte0);
		}
	}

	public String readAnsiString() {
		int i = readUnsignedShort();
		if (i == 0) {
			return "";
		} else {
			byte abyte0[] = readBytes(i);
			return new String(abyte0);
		}
	}

	public int length() {
		return writePos;
	}

	public void writeBoolean(boolean flag) {
		writeByte(flag ? 1 : 0);
	}

	public boolean readBoolean() {
		return readByte() != 0;
	}

	public float readFloat() {
		int i = readInt();
		return Float.intBitsToFloat(i);
	}

	public void reset() {
		readPos = 0;
	}

	public void writeLong(long l) {
		writeNumber(l, 8);
	}

	public ByteBuffer() {
		this(1024);
	}

	public ByteBuffer(int i) {
		data = new byte[i];
	}

	public ByteBuffer(byte abyte0[]) {
		this(abyte0, 0, abyte0.length);
	}

	public ByteBuffer(byte abyte0[], int i, int j) {
		data = abyte0;
		readPos = i;
		writePos = i + j;
	}

	public void writeShortAnsiString(String s) {
		if (s == null || s.length() == 0) {
			writeByte(0);
		} else {
			byte abyte0[] = s.getBytes();
			if (abyte0.length > 255)
				throw new IllegalArgumentException("short string over flow");
			writeByte(abyte0.length);
			writeBytes(abyte0);
		}
	}

	public long readLong() {
		return readNumber(8);
	}

	public void writeShort(int i) {
		writeNumber(i, 2);
	}

	public int readShort() {
		return (short) (int) (readNumber(2) & 65535L);
	}

	public void writeByteBuffer(ByteBuffer bytebuffer) {
		writeByteBuffer(bytebuffer, bytebuffer.available());
	}

	public void writeByteBuffer(ByteBuffer bytebuffer, int i) {
		ensureCapacity(length() + i);
		for (int j = 0; j < i; j++)
			data[writePos++] = bytebuffer.data[bytebuffer.readPos++];
	}

	public void writeBytes(byte abyte0[]) {
		writeBytes(abyte0, 0, abyte0.length);
	}

	public void writeBytes(byte abyte0[], int i, int j) {
		ensureCapacity(writePos + j);
		for (int k = 0; k < j; k++)
			data[writePos++] = abyte0[i++];
	}

	public byte[] readBytes(int i) {
		byte abyte0[] = new byte[i];
		for (int j = 0; j < i; j++)
			abyte0[j] = data[readPos++];
		return abyte0;
	}

	public int readUnsignedShort() {
		return (int) (readNumber(2) & 65535L);
	}

	public String readShortAnsiString() {
		int i = readUnsignedByte();
		if (i == 0) {
			return "";
		} else {
			byte abyte0[] = readBytes(i);
			return new String(abyte0);
		}
	}

	public int available() {
		return writePos - readPos;
	}

	public String toString() {
		return new String(data, 0, writePos);
	}

	public int getWritePos() {
		return writePos;
	}

	public void setWritePos(int i) {
		writePos = i;
	}

	public byte[] getRawBytes() {
		return data;
	}

	public void writeUTF(String s) {
		if (s == null)
			s = "";
		int i = s.length();
		int j = 0;
		for (int k = 0; k < i; k++) {
			char c = s.charAt(k);
			if (c < '\177')
				j++;
			else if (c > '\u07FF')
				j += 3;
			else
				j += 2;
		}
		if (j > 65535)
			throw new IllegalArgumentException("the string is too long:" + i);
		ensureCapacity(writePos + j + 2);
		writeShort(j);
		for (int l = 0; l < i; l++) {
			char c1 = s.charAt(l);
			if (c1 < '\177')
				data[writePos++] = (byte) c1;
			else if (c1 > '\u07FF') {
				data[writePos++] = (byte) (0xe0 | c1 >> 12 & 0xf);
				data[writePos++] = (byte) (0x80 | c1 >> 6 & 0x3f);
				data[writePos++] = (byte) (0x80 | c1 & 0x3f);
			} else {
				data[writePos++] = (byte) (0xc0 | c1 >> 6 & 0x1f);
				data[writePos++] = (byte) (0x80 | c1 & 0x3f);
			}
		}
	}

	@SuppressWarnings("unused")
	public String readUTF() {
		int i = readUnsignedShort();
		if (i == 0)
			return "";
		char ac[] = new char[i];
		int j = 0;
		boolean flag = false;
		boolean flag1 = false;
		boolean flag2 = false;
		for (int l = readPos + i; readPos < l;) {
			int k = data[readPos++] & 0xff;
			if (k < 127)
				ac[j++] = (char) k;
			else if (k >> 5 == 7) {
				byte byte0 = data[readPos++];
				byte byte2 = data[readPos++];
				ac[j++] = (char) ((k & 0xf) << 12 | (byte0 & 0x3f) << 6 | byte2 & 0x3f);
			} else {
				byte byte1 = data[readPos++];
				ac[j++] = (char) ((k & 0x1f) << 6 | byte1 & 0x3f);
			}
		}
		return new String(ac, 0, j);
	}

	public void clear() {
		writePos = readPos = 0;
	}

	public void writeInt(int i) {
		writeNumber(i, 4);
	}

	public int readInt() {
		return (int) (readNumber(4) & -1L);
	}

	public int position() {
		return readPos;
	}

	private int readPos;
	private int writePos;
	private byte data[];
}